package com.cn.goodsadmin.common.observes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by fly on 17/5/4.
 */
public class MessageManager {

    private static byte[] lock = new byte[0];//锁

    private final ReentrantLock mainLock = new ReentrantLock();

    private Condition condition;

    private static volatile MessageManager messageManager;//单例的统一消息管理

    private HashMap<Integer, List<IObservesr>> obserMap;//存储消息类型对应的观察者

    private List<Message> messages;//消息池

    private MessageManager() {
        obserMap = new HashMap<Integer, List<IObservesr>>();
        messages = new ArrayList<Message>();
    }

    /**
     * 单例的获取
     *
     * @return
     */
    public static MessageManager getInstanceMessage() {
        if (messageManager == null) {
            synchronized (lock) {
                if (messageManager == null) {
                    messageManager = new MessageManager();
                }
            }
        }
        //System.out.println("manager="+messageManager.toString());
        return messageManager;
    }

    /**
     * 注册观察者
     *
     * @param observeser
     * @param messageid
     */
    public synchronized void registerMessage(IObservesr observeser, Integer messageid) {
        List<IObservesr> list = obserMap.get(messageid);
        if (list == null) {
            list = new ArrayList<IObservesr>();
            obserMap.put(messageid, list);
        }
        list.add(observeser);
    }

    /**
     * 注销观察者
     *
     * @param observesr
     * @param messageid
     */
    public synchronized void unRegisterMessage(IObservesr observesr, Integer messageid) {
        List<IObservesr> list = obserMap.get(messageid);
        if (list != null) {
            list.remove(observesr);
        }
    }

    /**
     * 把消息放入消息池
     *
     * @param message
     */
    public void putMessage(Message message) {
        System.out.println(Thread.currentThread().getId() + "  等待锁 准备放入消息id==" + message.messageid);
        this.mainLock.lock();
        try {
            System.out.println(Thread.currentThread().getId() + "  获得锁锁");
            messages.add(message);

        } finally {
            System.out.println("condition=" + condition);
            if (condition == null) {
                condition = this.mainLock.newCondition();
            }
            condition.signal();
            this.mainLock.unlock();
            System.out.println("放入消息 释放锁 并且通知");
        }


    }


    /**
     * 消费消息
     */
    public void cosumeMessage() {

        while (true) {
            this.mainLock.lock();
            try {
                if (messages.size() == 0) {
                    try {
                        System.out.println("消费线程开始等待==" + Thread.currentThread().getId());
                        if (condition == null) {
                            condition = this.mainLock.newCondition();
                        }
                        System.out.println("开始等待");
                        condition.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                for (final Message message : messages) {
                    int messageid = message.messageid;
                    System.out.println("消息来了 开始发送广播 消息id=" + messageid);
                    List<IObservesr> list = obserMap.get(messageid);
                    if (list != null) {
                        System.out.println("消息来了 开始发送广播 监听人数=" + list.size());
                        if (list.size() > 0) {
                            for (final IObservesr observesr : list) {
                                observesr.onNoticeMessage(message);
                            }
                        }
                    }
                }
                messages.clear();
            } finally {
                this.mainLock.unlock();
                System.out.println("放入消息 释放锁");
            }
        }


    }

    /**
     * 销毁
     */
    public void clearAll(){
        obserMap.clear();
        messages.clear();
        obserMap=null;
        messages=null;
        messageManager=null;
    }


    public static void main(String[] agrs) {

    }
}
